import os
import aiohttp
from datetime import timedelta, timezone
from fastapi import APIRouter, Depends, HTTPException, status, Form
from sqlalchemy.ext.asyncio import AsyncSession
import json
from sqlalchemy import select
from typing import Any, Optional
from fastapi.security import OAuth2PasswordRequestForm
from jose import jwt, JWTError
from datetime import datetime

from app.config import Settings
from app.core.security import create_access_token, verify_password, get_current_user
from app.database import get_db
from app.models import User, Admin
from app.schemas import WechatLogin, AdminLogin
from app.schemas import resp_200, resp_4001, resp_500, Response
from app.core.logger import logger
from app.api.deps import get_current_admin

router = APIRouter(prefix="/auth")

class AdminInfo:
    def __init__(self, admin: Admin):
        self.id = admin.id
        self.username = admin.username
        self.display_name = admin.display_name
        self.avatar = admin.avatar
        self.permission = admin.permission

    def dict(self):
        return {
            "id": self.id,
            "username": self.username,
            "display_name": self.display_name,
            "avatar": self.avatar,
            "permission": self.permission
        }

@router.post("/wechat")
async def wechat_login(login_data: WechatLogin, db: AsyncSession = Depends(get_db)):
    """微信小程序登录"""

    if os.environ.get("MODE") == "development":
        access_token_expires = timedelta(minutes=Settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = create_access_token(
            data={"sub": str("2345678"), "type": "user"},
            expires_delta=access_token_expires,
        )
        return {"code": 10000, "data": access_token}

    try:
        # 微信登录API
        url = f"https://api.weixin.qq.com/sns/jscode2session?appid={Settings.WECHAT_APP_ID}&secret={Settings.WECHAT_APP_SECRET}&js_code={login_data.code}&grant_type=authorization_code"

        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                if response.status != 200:
                    raise HTTPException(
                        status_code=400, detail={"code": 50009, "data": "微信服务错误"}
                    )

                wechat_data = await response.json()
                if "errcode" in wechat_data and wechat_data["errcode"] != 0:
                    raise HTTPException(
                        status_code=400,
                        detail={
                            "code": 50009,
                            "data": f"微信服务错误: {wechat_data['errmsg']}",
                        },
                    )

                openid = wechat_data.get("openid")

                # 检查用户是否存在
                user = db.query(User).filter(User.openid == openid).first()

                if not user:
                    # 创建新用户
                    user = User(openid=openid)
                    db.add(user)
                    db.commit()
                    db.refresh(user)

                # 生成JWT令牌
                access_token_expires = timedelta(
                    minutes=Settings.ACCESS_TOKEN_EXPIRE_MINUTES
                )
                access_token = create_access_token(
                    data={"sub": str(user.id), "type": "user"},
                    expires_delta=access_token_expires,
                )

                return {"code": 10000, "data": access_token}

    except Exception as e:
        raise HTTPException(status_code=500, detail={"code": 50000, "data": str(e)})


@router.post("/login")
async def login(
    username: str = Form(...),
    password: str = Form(...),
    db: AsyncSession = Depends(get_db)
):
    try:
        result = await db.execute(
            select(Admin).where(Admin.username == username)
        )
        admin = result.scalar_one_or_none()

        if not admin:
            raise HTTPException(
                status_code=401,
                detail={"code": 30000, "data": "用户名或密码错误"}
            )

        if not verify_password(password, admin.password):
            raise HTTPException(
                status_code=401,
                detail={"code": 30000, "data": "用户名或密码错误"}
            )

        # 修正过期时间的计算
        access_token_expires = timedelta(minutes=Settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        expire_time = datetime.now(timezone.utc) + access_token_expires
        
        access_token = jwt.encode(
            {
                "sub": admin.username,
                "scopes": ["admin"],
                "id": admin.id,
                "permission": admin.permission,
                "exp": int(expire_time.timestamp())  # 使用正确的时间戳格式
            },
            Settings.SECRET_KEY,
            algorithm=Settings.ALGORITHM
        )

        return {
            "code": 10000,
            "data": {
                "access_token": access_token,
                "token_type": "bearer",
                "admin_info": AdminInfo(admin).dict()
            },
            "message": "Success"
        }
    except Exception as e:
        print(f"Login error: {str(e)}")
        raise HTTPException(
            status_code=500,
            detail={"code": 50000, "data": str(e)}
        )

@router.get("/verify")
async def verify_token(
    current_admin: Admin = Depends(get_current_admin)
):
    """验证 token 的有效性并返回管理员信息"""
    try:
        return {
            "code": 10000,
            "data": {
                "admin_info": AdminInfo(current_admin).dict(),
                "is_valid": True
            },
            "message": "Token is valid"
        }
    except Exception as e:
        raise HTTPException(
            status_code=401,
            detail={
                "code": 40100,
                "data": {
                    "is_valid": False,
                    "message": str(e)
                }
            }
        )
